package com.prb.client.factory;

import com.alibaba.fastjson.JSON;
import com.prb.netty.AsyncResult;
import com.prb.client.netty.Client;
import com.prb.netty.protocol.InvokeMsg;
import com.prb.netty.protocol.SmartCarProtocol;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.locks.LockSupport;

public class ProxyFactory {


    public static Object newProxy(Class... interfaces) {

        return Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(),
                interfaces ,
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        //调用的 序列化id 用于异步通知线程唤醒
                        String invokeId = UUID.randomUUID().toString();

                        InvokeMsg invokeMsg = new InvokeMsg();
                        invokeMsg.setInvokeId(invokeId);
                        invokeMsg.setArgs(Arrays.asList(args));
                        invokeMsg.setParamTypes(new Class[]{String.class});
                        invokeMsg.setClazz(interfaces[0]);
                        invokeMsg.setMethodName(method.getName());

                        Client.asyncMap.put(invokeId, new AsyncResult(invokeId, Thread.currentThread(), null));

                        SmartCarProtocol smartCarProtocol = new SmartCarProtocol(JSON.toJSONString(invokeMsg).getBytes().length , JSON.toJSONString(invokeMsg).getBytes());

                        Client.clientChannel.writeAndFlush(smartCarProtocol);

                        //锁定线程，等待调用rpc 返回 异步唤醒
                        LockSupport.park();

                        AsyncResult asyncResult = Client.asyncMap.get(invokeId);
                        Client.asyncMap.remove(invokeId);

                        return asyncResult.getResult();
                    }
                });

    }

}
